﻿using UnityEngine;
using UnityEditor;
using System.Collections;
using System.Collections.Generic;
using System.Text;

public class ComparisonAssetBundle
{

    [MenuItem("AssetBundle/ComparisonAssetBundle_Android     对比", false, 301)]
    public static void CompareAssetBundle_Android()
    {
        CompareAssetBundle(Platform.GetPlatformFolder(RuntimePlatform.Android));
    }

    [MenuItem("AssetBundle/ComparisonAssetBundle_IOS    对比", false, 302)]
    public static void CompareAssetBundle_IOS()
    {
        CompareAssetBundle(Platform.GetPlatformFolder(RuntimePlatform.IPhonePlayer));
    }

    [MenuItem("AssetBundle/ComparisonAssetBundle_Windows    对比", false, 303)]
    public static void CompareAssetBundle_Windows()
    {
        CompareAssetBundle(Platform.GetPlatformFolder(RuntimePlatform.WindowsEditor));
    }

    private static void CompareAssetBundle(string target_folder_name, string old_asset_bundle_full_path = null)
    {
        var new_asset_bundle_full_path = FileTool.PathCombine(AssetBundleConfig.AssetBundlesOutputPath, target_folder_name);

        if(string.IsNullOrEmpty(old_asset_bundle_full_path))
        {
            old_asset_bundle_full_path = FileTool.PathCombine(AssetBundleConfig.OldAssetBundleDirPath, target_folder_name);
           
            // 选择对比版本
            var temp_str = UnityEditor.EditorUtility.OpenFolderPanel("选择对比版本", old_asset_bundle_full_path, "");
            if(string.IsNullOrEmpty(temp_str))
            {
                // 第一个版本 的特殊处理办法
                var path = FileTool.PathCombine(old_asset_bundle_full_path, VersionTool.GetFirstVersion());
                if(!System.IO.Directory.Exists(path))
                {
                    old_asset_bundle_full_path = path;
                }
                else
                {
                    old_asset_bundle_full_path = FileTool.PathCombine(old_asset_bundle_full_path, VersionTool.GetLastestVersion());
                }
            }
            else
            {
                old_asset_bundle_full_path = temp_str;
            }
        }

        var temp_dir_path = FileTool.PathCombine(AssetBundleConfig.TempAssetBundleDirPath,target_folder_name);
        var dir = CompareAssetBundle(new_asset_bundle_full_path, old_asset_bundle_full_path, temp_dir_path);
        List<string> file_names = new List<string>(dir.Keys);
        FinishComparion(temp_dir_path, file_names);
    }

    /// <summary>
    /// 比较新旧包
    /// </summary>
    /// <param name="new_asset_bundle_full_path">新的AssetBundle存放目录路径</param>
    /// <param name="old_asset_bundle_full_path">旧的AssetBundle存放目录路径</param>
    /// <param name="temp_dir_path">临时目录路径名称</param>
    /// <returns>不同的文件表</returns>
    public static Dictionary<string, string> CompareAssetBundle(string new_asset_bundle_full_path, string old_asset_bundle_full_path, string temp_dir_path)
    {
        RemoveTempBundleForlder(temp_dir_path);

        // 获取新的包的 hash_text
        var new_hash_code_text_full_path = FileTool.PathCombine(new_asset_bundle_full_path, AssetBundleConfig.HashCodeFileName);
        var new_text = FileTool.ReadFileContent(new_hash_code_text_full_path);
        var new_dir = GetHashTable(new_text);

        // 获取旧的包的 hash_text
        var old_hash_code_text_full_path = FileTool.PathCombine(old_asset_bundle_full_path, AssetBundleConfig.HashCodeFileName);
        var old_text = FileTool.ReadFileContent(old_hash_code_text_full_path);
        var old_dir = GetHashTable(old_text);

        // 对比出不同的包
        // 复制到临时目录
        var different_dir = GetDifferentBundlePath(old_dir, new_dir);
        foreach(var dir_item in different_dir)
        {
            var file_part_name = dir_item.Key;
            var form_path = FileTool.PathCombine(new_asset_bundle_full_path, file_part_name);
            var to_path = FileTool.PathCombine(temp_dir_path, file_part_name);

            var content = FileTool.ReadFileContent(form_path);
            FileTool.WriteFileContent(to_path, content);
        }
        var _content = FileTool.ReadFileContent(new_hash_code_text_full_path);
        var to_hash_code_text = FileTool.PathCombine(temp_dir_path, AssetBundleConfig.HashCodeFileName);
        FileTool.WriteFileContent(to_hash_code_text, _content);

        return different_dir;
    }

    /// <summary>
    /// 获取不同的AssetBundle
    /// </summary>
    /// <param name="url"></param>
    /// <param name="hash_code_text"></param>
    /// <returns>不同表</returns>
    public static Dictionary<string, string> GetDifferentBundlePath(Dictionary<string, string> old_hash_code_map, Dictionary<string, string> new_hash_code_map)
    {
        var different_map = new Dictionary<string, string>();

        // 对比表
        // 没有新旧表的处理办法
        // 有新旧表的处理办法
        // 新旧表对比更新方法
        if (old_hash_code_map.Count <= 0)       // 没有旧表
        {
            foreach (var map_item in new_hash_code_map)
            {
                different_map.Add(map_item.Key,map_item.Value);
            }
        }
        else if (new_hash_code_map.Count <= 0)  // 没有新表
        {
            // 不做任何事 
            Debug.LogWarning("Can't get new hash code  ");
        }
        else
        {   
            // 新旧表更新
            // 获取新增表
            // 获取修改表
            foreach (var new_hash_item in new_hash_code_map)
            {
                var key = new_hash_item.Key;
                if (old_hash_code_map.ContainsKey(key))
                {
                    var old_val = old_hash_code_map[key];
                    var new_val = new_hash_item.Value;
                    if (!old_val.Equals(new_val))
                    {
                        different_map.Add(key, new_val);
                    }
                }
                else
                {
                    different_map.Add(key, new_hash_item.Value);
                }
            }
        }

        return different_map;
    }

    private static Dictionary<string, string> GetHashTable(string text)
    {
        var map = new Dictionary<string, string>();
        if (!string.IsNullOrEmpty(text))
        {
            var strs = text.Split('\n');
            foreach (var str in strs)
            {
                var _str = str.Split('=');
                map.Add(_str[0], _str[1]);
            }
        }
        return map;
    }

    private static void RemoveTempBundleForlder(string temp_dir_path)
    {
        FileTool.ForeachFiles(temp_dir_path, FileTool.ForeachEnum.FileAndDir, (string path) =>
            {
                FileUtil.DeleteFileOrDirectory(path);
            });
        FileUtil.DeleteFileOrDirectory(temp_dir_path);
    }

    private static void FinishComparion(string temp_path,List<string> file_name_list)
    {

        if(file_name_list.Count > 0)
        {
            StringBuilder builder = new StringBuilder();
            builder.Append("更新文件如下:\n");
            foreach(var file_name in file_name_list)
            {
                builder.Append(FileTool.PathCombine(temp_path, file_name));
                builder.Append("\n");
            }
            Debug.Log(builder.ToString());
        }
        
        if(EditorUtility.DisplayDialog("结束","是否打开更新后的文件夹","确定","取消"))
        {
            System.Diagnostics.Process.Start("Explorer",@"file:///" + temp_path);
        }
        Debug.Log("对比完成  更新个数： " + file_name_list.Count);
    }

}
